﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using AidBrella.Models;
using System.Web.Security;
using System.Security.Principal;

namespace AidBrella.BLL
{
    /// <summary>
    /// Identity and authentication parts (mainly adapted from solutions on web)
    /// </summary>
    public class UserModel:BaseModel
    {
        public UserSet GetUser(string userName, string pass)
        {
            return _entities.UserSet.Where(o => o.UserName == userName && o.Password == pass).FirstOrDefault();           
        }

        public UserSet GetUser(int userId)
        {
            return _entities.UserSet.Where(o => o.Id == userId).FirstOrDefault();
        }

        public MembershipUser CreateUser(string username, string password, string email, string firstName, string lastName)
        {
            UserSet user = new UserSet();
            user.UserName = username;
            user.Email = email;
            user.FirstName = firstName;
            user.LastName = lastName;          
            user.PasswordSalt = Common.CreateSalt();
            user.Password = Common.CreatePasswordHash(password,user.PasswordSalt);
            user.IsActivated = false;
            user.IsLockedOut = false;
            _entities.UserSet.AddObject(user);
            SaveChanges();

           return GetUser(username);
        }

        public string GetUserNameByEmail(string email)
        {
            var result = _entities.UserSet.Where(o => o.Email == email);
            if (result.Count() == 0)
                return "";
            else
            {
                var dbuser = result.FirstOrDefault();
                return dbuser.UserName;
            }
        }

        public MembershipUser GetUser(string username)
        {
            
            var result = _entities.UserSet.Where(u => u.UserName == username);

            if (result.Count() != 0)
            {
                var dbuser = result.FirstOrDefault();

                string _username = dbuser.UserName;
                int _providerUserKey = dbuser.Id;
                string _email = dbuser.Email;
                string _passwordQuestion = "";               
                bool _isApproved = dbuser.IsActivated;
                bool _isLockedOut = dbuser.IsLockedOut;
                DateTime _creationDate = dbuser.Created != null ? dbuser.Created.Value : DateTime.Now;
                DateTime _lastLoginDate = dbuser.LastLoginDate != null ? dbuser.LastLoginDate.Value : DateTime.Now ;
                DateTime _lastActivityDate = DateTime.Now;
                DateTime _lastPasswordChangedDate = DateTime.Now;
                DateTime _lastLockedOutDate = dbuser.LastLockedOutDate != null ? dbuser.LastLockedOutDate.Value : DateTime.Now;


                MembershipUser user = new MembershipUser("CustomMembershipProvider",
                                                            _username,
                                                            _providerUserKey,
                                                            _email,
                                                            _passwordQuestion,
                                                             string.Empty,
                                                            _isApproved,
                                                            _isLockedOut,
                                                            _creationDate,
                                                            _lastLoginDate,
                                                            _lastActivityDate,
                                                            _lastPasswordChangedDate,
                                                            _lastLockedOutDate);

               

                return user;
            }
            else
            {
                return null;
            }
        }

        public bool ValidateUser(string username, string password)
        {
            
            var result = _entities.UserSet.Where( u=> u.UserName == username);

            if (result.Count() != 0)
            {
                var dbuser = result.First();

                if (dbuser.Password == Common.CreatePasswordHash(password, dbuser.PasswordSalt))
                    return true;
                else
                    return false;
            }
            else
            {
                return false;
            }
            
        }

        public UserSet GetValidatedUser(string username, string password)
        {

            var result = _entities.UserSet.Where(u => u.UserName == username);

            if ( result.Count() != 0)
            {
                var dbuser = result.First();

                if (dbuser.Password == Common.CreatePasswordHash(password, dbuser.PasswordSalt))
                    return dbuser;
               
            }
            return null;     
        }

        public int GetUserId(string userName)
        {
            var result = _entities.UserSet.Where(u => u.UserName == userName);

            if (result.Count() == 1)
                return result.FirstOrDefault().Id;

            return 0;
        }

        /// <summary>
        /// Returns All the projects the user is following
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public IEnumerable<UserFollowProject> GetProjectsUserFollows(int userId)
        {
            return _entities.UserFollowProject.Where(o => o.UserId == userId);
        }

        public string GetUserFullNameById(int userId)
        {
            var user = _entities.UserSet.Where(u => u.Id == userId).FirstOrDefault();

            return string.Format("{0} {1}", user.FirstName, user.LastName);
        }

    }

    public class Identity : IIdentity
    {
        readonly bool isAuthenticated;
        readonly string name;
        readonly int userId;

        public Identity(bool isAuthenticated, string name, int userid)
        {
            this.isAuthenticated = isAuthenticated;
            this.name = name;
            this.userId = userid;
        }

        #region IIdentity Members

        public string AuthenticationType
        {
            get { return "Forms"; }
        }

        public bool IsAuthenticated
        {
            get { return isAuthenticated; }
        }

        public string Name
        {
            get { return name; }
        }

        public int UserId { get { return userId; } }

        #endregion
    }

    public class LoginUserGroup
    {
        public string Name { get; set; }
        public Guid Id { get; set; }
    }

    public class LogedInUser : IPrincipal
    {
        public string UserName { get; private set; }
        public string Password { get; private set; }
        private List<LoginUserGroup> UserGroups { get; set; }
        public int UserId { get; private set; }

        public LogedInUser(string userName, List<LoginUserGroup> userGroups, int userId)
        {
            UserName = userName;

            UserGroups = userGroups;
            UserId = userId;
        }

        public LogedInUser(string userName, int userId)
        {
            UserName = userName;
            UserId = userId;
        }

        public IIdentity Identity
        {
            get
            {
                bool isAuthenticated = true;
                return new Identity(isAuthenticated, this.UserName, this.UserId);
            }
        }

        public bool IsInRole(string groupName)
        {
            return UserGroups.Any(group => group.Name.ToUpper() == groupName.ToUpper());
        }

        public bool IsInRole(Guid groupId)
        {
            return UserGroups.Any(group => group.Id == groupId);
        }
    }

    
}